package com.chenxin.wms.process.inbound.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chenxin.common.annotation.WmsLogs;
import com.chenxin.common.core.domain.ProcResult;
import com.chenxin.common.enums.wms.*;
import com.chenxin.common.utils.StringUtils;
import com.chenxin.wms.domain.*;
import com.chenxin.wms.domain.dto.DeliverRegisterParams;
import com.chenxin.wms.domain.po.StationInfo;
import com.chenxin.wms.mapper.*;
import com.chenxin.wms.process.inbound.IProcDeliverRegister;
import com.chenxin.wms.process.inbound.IProcIbMasterStatusUpdate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class ProcDeliverRegisterImpl implements IProcDeliverRegister {
    @Autowired
    private DeliverDetailMapper deliverDetailMapper;
    @Autowired
    private IbDetailMapper ibDetailMapper;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private StockMapper stockMapper;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private IProcIbMasterStatusUpdate procIbMasterStatusUpdate;

    @WmsLogs(name = "收货登记")
    @Transactional
    @Override
    public ProcResult call(DeliverRegisterParams params) {
        if (params == null) {
            return ProcResult.error("deliver_register_000", "请求参数不能为空");
        }
        // 收货单明细ID
        Long deliverDetailId = params.getDeliverDetailId();
        if (deliverDetailId == null) {
            return ProcResult.error("deliver_register_001", "收货单明细ID不能为空");
        }
        // 收货站台
        String stationNo = params.getStationNo();
        if (StringUtils.isEmpty(stationNo)) {
            return ProcResult.error("deliver_register_002", "收货站台不能为空");
        }
        // 收货托盘
        String contNo = params.getContNo();
        if (StringUtils.isEmpty(contNo)) {
            return ProcResult.error("deliver_register_001", "收货LPN不能为空");
        }
        // 收货数量
        BigDecimal inQty = params.getInQty();
        if (inQty == null || inQty.compareTo(BigDecimal.ZERO) <= 0) {
            return ProcResult.error("deliver_register_003", "收货数量不能小于等于0");
        }
        // 批次号
        String lotNo = params.getLotNo();
        // RELID
        String reelId = params.getReelId();
        // 作业员 (补充判断是否为作业员)
        Long creator = params.getCreator();
        // 作业时间
        Date workDate = new Date();

        // 逻辑处理，通过ID获取收货单明细信息
        DeliverDetailEntity deliverDetail = deliverDetailMapper.selectById(deliverDetailId);
        if (deliverDetail == null) {
            return ProcResult.error("deliver_register_004", "收货单明细ID【" + deliverDetailId + "】不存在,请核查");
        }
        // 校验单据状态是否可收货（状态以及本次预约数量-收货数量）
        Integer status = deliverDetail.getStatus();
        if (status > 1) {
            return ProcResult.error("deliver_register_008", "收货单明细ID【" + deliverDetailId + "】当前状态【" + status + "】不允许收货");
        }
        // 预约数量-收货数量
        BigDecimal remainQty = deliverDetail.getShpQty().subtract(deliverDetail.getInQty());
        if (remainQty.compareTo(inQty) < 0) {
            return ProcResult.error("deliver_register_009", "收货单明细ID【" + deliverDetailId + "】当前收货数量【" + inQty + "】大于可收货数量【" + remainQty + "】，不允许收货");
        }
        // 收货单详情
        String ebeln = deliverDetail.getPoNo();
        String ebelp = deliverDetail.getPoLine();
        String spuNo = deliverDetail.getSpuNo();
        // 根据采购单号和行项目号查询采购单详情（匹配未收货完成的单据）
        QueryWrapper<IbDetailEntity> ibDetailQW = new QueryWrapper<>();
        ibDetailQW.lambda().eq(IbDetailEntity::getEbeln, ebeln).eq(IbDetailEntity::getEbelp, ebelp)
                .lt(IbDetailEntity::getIbDetailStatus, IbDetailStatus.DONE.getCode());
        IbDetailEntity ibDetail = ibDetailMapper.selectOne(ibDetailQW);
        if (ibDetail == null) {
            return ProcResult.error("deliver_register_011", "收货单明细ID【" + deliverDetailId + "】未匹配到采购订单【" + ebeln + "】,行项目号【" + ebelp + "】");
        }
        // 采购单详情
        Long ibDetailId = ibDetail.getIbDetailId();
        int ibDetailStatus;
        Long ibMasterId = ibDetail.getIbMasterId();
        String ibMasterNo = ibDetail.getIbMasterNo();
        BigDecimal ibPlanQty = ibDetail.getIbPlanQty();
        BigDecimal ibActualQty = ibDetail.getIbActualQty();
        // 采购单可收货数量
        BigDecimal remainIbQty = ibPlanQty.subtract(ibActualQty);
        // 收货物料信息校验
        QueryWrapper<SpuEntity> spuQW = new QueryWrapper<>();
        spuQW.eq("spu_no", spuNo).eq("spu_status", 0);
        SpuEntity spuInfo = spuMapper.selectOne(spuQW);
        if (spuInfo == null) {
            return ProcResult.error("deliver_register_005", "收货单明细ID【" + deliverDetailId + "】中收货物料【" + spuNo + "】未维护或不可用,请核查");
        }
        Long zoneIdBySpu = spuInfo.getZoneId();
        // 是否免检
        Integer isQuality = spuInfo.getIsQuality();
        // 判断物料是否维护了默认上架区域
        if (zoneIdBySpu == null) {
            return ProcResult.error("deliver_register_006", "收货单明细ID【" + deliverDetailId + "】中物料【" + spuNo + "】未维护上架库区,请核查");
        }
        if (spuInfo.getWarehouseId() == null) {
            return ProcResult.error("deliver_register_007", "收货单明细ID【" + deliverDetailId + "】中物料【" + spuNo + "】未维护仓库信息,请核查");
        }

        // 收货站台信息校验
        StationInfo stationInfo = stationMapper.selectStationInfoByNo(stationNo);
        if (stationInfo == null) {
            return ProcResult.error("deliver_register_010", "收货站台【" + stationNo + "】未维护,请核查");
        }
        // 只有入库站台或者双向站台可用于收货
        Long zoneIdByStation = stationInfo.getZoneId();
        String stationType = stationInfo.getStationType();
        if (!StationType.SI.getCode().equals(stationType)) {
            return ProcResult.error("deliver_register_013", "收货站台【" + stationNo + "】类型【" + stationType + "】不允许收货");
        }
        // 获取收货站台对应的虚拟货位
        String fromPosition = stationInfo.getLocationNo();
        if (StringUtils.isEmpty(fromPosition)) {
            return ProcResult.error("deliver_register_011", "收货站台【" + stationNo + "】未配置对应的货位信息,请核查");
        }
        // 收货站台所属区域必须与物料的上架区域一致
        if (!zoneIdBySpu.equals(zoneIdByStation)) {
            return ProcResult.error("deliver_register_012", "收货物料【" + spuNo + "】的上架库区与收货站台【" + stationNo + "】所属库区不一致,请核查");
        }
        // 校验托盘是否混载
        QueryWrapper<StockEntity> stockQW = new QueryWrapper<>();
        stockQW.lambda().eq(StockEntity::getContNo, contNo);
        List<StockEntity> existsStocks = stockMapper.selectList(stockQW);
        if (existsStocks != null && existsStocks.size() > 0) {
            for (StockEntity stock : existsStocks) {
                // 检查所有库存的所在位置是否与当前收货位置一致
                if (!fromPosition.equals(stock.getLocationNo())) {
                    return ProcResult.error("deliver_register_013", "LPN【" + contNo + "】已存在其他位置的库存，不能用于本次收货，收货明细【" + deliverDetailId + "】");
                }
                // 不同批次的物料不能收取到同一个托盘上（混批校验）
                if (!stock.getLotNo().equals(lotNo)) {
                    return ProcResult.error("deliver_register_014", "LPN【" + contNo + "】已存在其他批次的库存，不能用于本次收货，收货明细【" + deliverDetailId + "】");
                }
            }
        }

        // 校验托盘是否存在其他业务场景的搬运任务
        QueryWrapper<TaskEntity> taskQW = new QueryWrapper<>();
        taskQW.lambda().eq(TaskEntity::getFromContNo, contNo)
                .lt(TaskEntity::getTaskStatus, TaskStatus.DONE.getCode());
        List<TaskEntity> existsTasks = taskMapper.selectList(taskQW);
        if (existsTasks != null && existsTasks.size() > 0) {
            for (TaskEntity task : existsTasks) {
                if (!task.getTaskSubType().equals(TaskType.SUB_GOODS_IN.getCode())) {
                    return ProcResult.error("wip_register_015", "LPN【" + contNo + "】已存在其他场景任务，不能用于本次收货，收货明细【" + deliverDetailId + "】");
                }
            }
        }
        // 数据校验无误后写入库存、任务等信息
        StockEntity registerStock = new StockEntity();
        registerStock.setContNo(contNo);
        registerStock.setLocationNo(fromPosition);
        registerStock.setSpuNo(spuNo);
        registerStock.setLotNo(lotNo);
        registerStock.setStockQty(inQty);
        // 免检=合格 非免检=待检
        registerStock.setQualityStatus(StockQuality.QA.getCode());
        registerStock.setReelId(reelId);
        registerStock.setIbDetailId(ibDetailId);
        registerStock.setSupplierNo(deliverDetail.getSupplierNo());
        registerStock.setEbeln(ebeln);
        registerStock.setEbelp(ebelp);
        registerStock.setCreator(creator);
        registerStock.setCreateDate(workDate);
        // 写入库存
        stockMapper.insert(registerStock);
        // 收货登记任务
        TaskEntity registerTask = new TaskEntity();
        registerTask.setTaskType(TaskType.RECEIVE_IN.getCode());
        registerTask.setTaskSubType(TaskType.SUB_GOODS_IN.getCode());
        registerTask.setTaskStatus(TaskStatus.INIT.getCode());
        registerTask.setFromContNo(contNo);
        // 10.1存放物料信息
        registerTask.setSpuNo(spuNo);
        registerTask.setLotNo(lotNo);
        registerTask.setPlanQty(inQty);
        registerTask.setMasterNo(ibMasterNo);
        registerTask.setMasterId(ibMasterId);
        registerTask.setDetailId(ibDetailId);
        //10.2 货位位置信息
        registerTask.setFromPosition(fromPosition);
        registerTask.setCurPosition(fromPosition);
        registerTask.setToPosition("");
        registerTask.setStationNo(stationNo);
        // 写入关联库存ID
        registerTask.setEbeln(ebeln);
        registerTask.setEbelp(ebelp);
        registerTask.setStockId(registerStock.getStockId());
        registerTask.setCreator(creator);
        registerStock.setCreateDate(workDate);
        // 10.3写入任务
        taskMapper.insert(registerTask);
        // 更新送货单信息
        if (inQty.compareTo(remainQty) < 0) {
            deliverDetail.setStatus(IbDetailStatus.EXEC.getCode());
        } else {
            deliverDetail.setStatus(IbDetailStatus.DONE.getCode());
        }
        deliverDetail.setInQty(deliverDetail.getInQty().add(inQty));
        deliverDetail.setUpdater(creator);
        deliverDetail.setUpdateDate(workDate);
        deliverDetailMapper.updateById(deliverDetail);

        // 更新采购单信息
        if (inQty.compareTo(remainIbQty) < 0) {
            ibDetailStatus = IbDetailStatus.EXEC.getCode();
        } else {
            ibDetailStatus = IbDetailStatus.DONE.getCode();
        }
        ibDetail.setIbDetailStatus(ibDetailStatus);
        ibDetail.setIbActualQty(ibDetail.getIbActualQty().add(inQty));
        ibDetail.setUpdater(creator);
        ibDetail.setUpdateDate(workDate);
        ibDetailMapper.updateById(ibDetail);

        // 更新主单状态
        //procIbMasterStatusUpdate.statusUpdateByMasterId(ibMasterId, creator);
        return ProcResult.success("收货成功，收货ID【" + deliverDetailId + "】，LPN【" + contNo + "】物料【" + spuNo + "】收货数量【" + inQty + "】，作业站台【" + stationNo + "】");
    }
}
